package cn.iocoder.yudao.module.promotion.redpacket.service.app;

import cn.iocoder.yudao.framework.business.basic.dao.query.CoreQueryWrapper;
import cn.iocoder.yudao.framework.business.basic.service.PageService;
import cn.iocoder.yudao.framework.business.basic.service.impl.BaseService;
import cn.iocoder.yudao.framework.common.util.number.MoneyUtils;
import cn.iocoder.yudao.module.api.promotion.redpacket.enums.RedPacketDiscountModeEnum;
import cn.iocoder.yudao.module.api.promotion.redpacket.vo.RedPacketAmountVO;
import cn.iocoder.yudao.module.api.promotion.redpacket.vo.RedPacketUsageVO;
import cn.iocoder.yudao.module.promotion.redpacket.dao.RedPacketActivityMapper;
import cn.iocoder.yudao.module.promotion.redpacket.dao.RedPacketRecordMapper;
import cn.iocoder.yudao.module.promotion.redpacket.pojo.dto.RedPacketRecordQueryDTO;
import cn.iocoder.yudao.module.promotion.redpacket.pojo.po.RedPacketActivity;
import cn.iocoder.yudao.module.promotion.redpacket.pojo.po.RedPacketConfig;
import cn.iocoder.yudao.module.promotion.redpacket.pojo.po.RedPacketRecord;
import cn.iocoder.yudao.module.promotion.redpacket.pojo.vo.RedPacketRecordVO;
import cn.iocoder.yudao.module.promotion.redpacket.service.core.CoreRedPacketConfigService;
import cn.iocoder.yudao.module.promotion.redpacket.service.core.CoreRedPacketRecordService;
import jakarta.annotation.Nonnull;
import jakarta.annotation.Nullable;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import java.time.LocalTime;

/**
 * <pre>
 * OOoO0OOoO0OOOooo0oOOOO0OOOOO0oooOO0ooOOO0Ooooo0OOOOo0ooooO0OOooo0Ooooo0OOOOO
 * 服务
 * OOoO0OOoO0OOOooo0oOOOO0OOOOO0oooOO0ooOOO0Ooooo0OOOOo0ooooO0OOooo0Ooooo0OOOOO
 * </pre>
 *
 * @author 山野羡民（1032694760@qq.com）
 * @since 2025/06/21
 */
@Slf4j
@Service
public class AppRedPacketRecordService extends BaseService<RedPacketRecord, RedPacketRecordVO, RedPacketRecordQueryDTO> implements PageService<RedPacketRecordVO, RedPacketRecordQueryDTO> {
    @Resource
    private RedPacketRecordMapper redPacketRecordMapper;
    @Resource
    private RedPacketActivityMapper redPacketActivityMapper;

    @Resource
    @Lazy // 延迟加载，避免循环依赖
    private CoreRedPacketConfigService coreRedPacketConfigService;
    @Resource
    @Lazy // 延迟加载，避免循环依赖
    private CoreRedPacketRecordService coreRedPacketRecordService;

    @Override
    public RedPacketRecordMapper getInjectedMapper() {
        return redPacketRecordMapper;
    }

    @Nonnull
    @Override
    protected CoreQueryWrapper<RedPacketRecord> buildQueryWrapper(RedPacketRecordQueryDTO param) {
        CoreQueryWrapper<RedPacketRecord> wrapper = super.buildQueryWrapper(param);
        wrapper.eqIfPresent("shop_id", param.getShopId());
        wrapper.eqIfPresent("source", param.getSource());
        return wrapper;
    }

    @Nonnull
    public RedPacketUsageVO getMatchedRedPacket(@Nullable Long userId, Long shopId, Integer orderAmount) {
        RedPacketUsageVO redPacketUsageVO = new RedPacketUsageVO();
        redPacketUsageVO.setNewCustomerRedPacketAmount(0);
        redPacketUsageVO.setDiscountMode(RedPacketDiscountModeEnum.FIXED.getValue());
        if (userId == null || userId <= 0) {
            // 未登录的情况下，当成新客处理
            RedPacketConfig config = coreRedPacketConfigService.getOrCreate(shopId);
            if (Boolean.TRUE.equals(config.getFeatureEnable())) {
                redPacketUsageVO.setTotalRedPacketAmount(config.getFirstAmount());
                redPacketUsageVO.setUnusedRedPacketAmount(config.getFirstAmount() > 0 ? 1 : 0);
                redPacketUsageVO.setCanDiscountPrice(Math.min(orderAmount, config.getFirstAmount()));
                redPacketUsageVO.setCannotDiscountReason("登录后享红包抵扣");
                return redPacketUsageVO;
            }
            redPacketUsageVO.setTotalRedPacketAmount(0);
            redPacketUsageVO.setUnusedRedPacketAmount(0);
            redPacketUsageVO.setCanDiscountPrice(0);
            redPacketUsageVO.setCannotDiscountReason("红包功能未开启");
            return redPacketUsageVO;
        }
        // 已登录的情况下，尝试自动发放新客红包
        RedPacketRecord newCustomerRedPacket = coreRedPacketRecordService.grantNewCustomerRedPacketIfNecessary(userId, shopId);
        if (newCustomerRedPacket != null) {
            redPacketUsageVO.setNewCustomerRedPacketAmount(newCustomerRedPacket.getAmount());
        }
        // 查询用户的已生效、未过期且未使用的红包
        RedPacketAmountVO redPacketAmount = coreRedPacketRecordService.getRedPacketAmount(userId, shopId);
        if (redPacketAmount.getUnusedAmount() <= 0) {
            log.debug("用户[{}]在店铺[{}]下没有可用红包", userId, shopId);
            redPacketUsageVO.setTotalRedPacketAmount(0);
            redPacketUsageVO.setUnusedRedPacketAmount(0);
            redPacketUsageVO.setCanDiscountPrice(0);
            redPacketUsageVO.setCannotDiscountReason("没有可用红包");
            return redPacketUsageVO;
        }
        redPacketUsageVO.setTotalRedPacketAmount(redPacketAmount.getTotalAmount());
        redPacketUsageVO.setUnusedRedPacketAmount(redPacketAmount.getUnusedAmount());
        // 根据时间及门槛查询店铺的红包抵扣规则
        LocalTime nowTime = LocalTime.now();
        RedPacketActivity redPacketActivity = redPacketActivityMapper.selectMatchedOne(shopId, orderAmount, nowTime);
        if (redPacketActivity == null) {
            log.debug("店铺[{}]没有满足订单金额[{}]在当前时间[{}]的红包活动", shopId, orderAmount, nowTime);
            redPacketUsageVO.setCanDiscountPrice(0);
            redPacketUsageVO.setCannotDiscountReason("不在指定时段内");
            return redPacketUsageVO;
        }
        redPacketUsageVO.setDiscountMode(redPacketActivity.getDiscountMode());
        int discountPrice = redPacketActivity.getDiscountPrice();
        redPacketUsageVO.setCanDiscountPrice(discountPrice);
        redPacketUsageVO.setCannotDiscountReason("可抵扣" + MoneyUtils.fenToYuanStr(discountPrice) + "元");
        return redPacketUsageVO;
    }

    public int getGrantedRedPacket(String tradeNo) {
        return redPacketRecordMapper.sumAmountByTradeNo(tradeNo);
    }

}
